package com.ruoyi.im.utils;

import com.alibaba.fastjson2.JSON;
import com.ruoyi.im.controller.ServerEndPoint;
import com.ruoyi.im.entity.MsgRoute;
import com.ruoyi.im.service.OffLineMsgService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import javax.websocket.Session;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;

import static com.ruoyi.im.controller.ServerEndPoint.onlineSessionList;

@Component
public class RouteQueueUtil {

    @Value("${server.port}")
    private String port;

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private  OffLineMsgService offLineMsgService;
    @Autowired
    private  AmqpTemplate amqpTemplate;

    @Autowired
    private ApplicationContext applicationContext;
    private static final Logger LOGGER = LoggerFactory.getLogger(ServerEndPoint.class);
    /**
     * 集群服务交换机
     * 通过路由key，路由到不同服务对应的队列中
     */
    public static final String AMQP_SERVER_EXCHANGE_PREFIX = "server_msg_exchange";

    /**
     * 获取路由key
     *
     * @return
     */
    public String getRouteKey() {
        InetAddress localhost = null;
        try {
            localhost = InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
            throw new RuntimeException(e);
        }
        String hostAddress = localhost.getHostAddress();

        return hostAddress + ":" + port;
    }

    public void msgToPerson(MsgRoute msgRoute) {
        if (msgRoute.getMsgId() == null) {
            throw new RuntimeException("消息编号为空");
        }
        Integer receiverId = msgRoute.getReceiverId();
        //查询接收者所在的server
        ValueOperations<String, Object> vo = redisTemplate.opsForValue();
        Object o = vo.get("ws:session:cluster:id:" + receiverId);
        if (o == null) {
            //不在线，消息存放到离线消息中
            offLineMsgService.addNewOfflineMsg(msgRoute);
            return;
        }
        String serverId = (String) o;
        //判断消息是否在本机
        String routeKey = getRouteKey();

        if (routeKey.equals(serverId)) {
            LOGGER.info("本机直发{}", serverId);
            //直接发送
            Session session = onlineSessionList.get(receiverId);
            if (session == null || !session.isOpen()) {
                //当前用户不存在，存放到离线消息中
                offLineMsgService.addNewOfflineMsg(msgRoute);
                return;
            }
            try {
                session.getBasicRemote().sendText(JSON.toJSONString(msgRoute));
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            return;
        }
        //将消息投递到对应的队列中
        amqpTemplate.convertAndSend(AMQP_SERVER_EXCHANGE_PREFIX, serverId + "", JSON.toJSONString(msgRoute));
    }


}
